
<style lang="scss" scoped>

  $total_width:1200px;

  $left_width:720px;

  $width:480px;

  $height:440px;

  $border-header:1px;

  $header-height:80px;

  $cell-width:40px;

  $cell-group-width:$cell-width*6;

  $date-width:180px;

  $line-height:45px;

  $slider-height:24px;

  $border-color:#ccc;


  [v-cloak]{
    visibility: hidden;
  }

  .container{
    width:$left_width+$width;
    height: $height;
    display: block;
    background: white;
    margin:0px auto;
    clear: both;
  }

  .chart-left-header{
    width:$left_width;
    height:$header-height;
    float: left;
    display: block;
    line-height: 80px;
    font-family: '微软雅黑';
    border: 1px solid $border-color;
    border-right: none;
    /*box-sizing: border-box;*/
    overflow: hidden;
    .text-header-item{
      height: 80px;
      color: black;
      display: block;
      text-align: center;
      border-right: 1px solid $border-color;
      float: left;
      /*box-sizing: border-box;*/
    }

    .number-item{
      width:50px;
      @extend .text-header-item;
    }

    .project-item{
      width:120px;
      @extend .text-header-item;
    }

    .project-subitem{
      width:140px;
      @extend .text-header-item;
    }

    .date-item{
      width: $date_width;
      @extend .text-header-item;
    }

    .total-date{
      width:49px;
      @extend .text-header-item;
      border-right: none;
    }

  }

  .chart-right-header{
    width: $width;
    height:auto;
    float: left;
    display: block;
    /*box-sizing: border-box;*/
  }

  .chart-container-wrapper{
    width: $total_width;
    height:$height+1px;
    float:right;
    overflow-x: scroll;
  }

  .chart-body-container{
    width: $total_width;
    height: 100%;
    background: white;
  }

  .chart-project-item{
    width: $total_width;
    /*<!--border-bottom:1px solid $border-color;-->*/
    clear: both;
    height: auto;
    float: left;

    .row-number{
      width:50px;
      float: left;
      height:100%;
      display: block;
      text-align: center;
      min-height:45px;
      border-left: 1px solid $border-color;
      border-bottom: 1px solid $border-color;
    }


    .row-project{
      width:120px;
      /*height:100%;*/
      min-height: 45px;
      float: left;
      display: block;
      text-align: center;
      border-left: 1px solid $border-color;
      border-bottom: 1px solid $border-color;
      white-space: nowrap;
      padding: 0 10px;
      text-overflow: ellipsis;
      overflow: hidden;
    }

    .row-sub-container{
      width:550px;
      min-height: 45px;
      display: block;
      float: left;

      .subproject-item{
        line-height: 45px;
        height: 45px;
        text-align: center;
        width:140px;
        float: left;
        border-left: 1px solid $border-color;
        border-bottom: 1px solid $border-color;
        padding:0px 10px;
      }

      .begin-date,
      .end-date{
        line-height: 45px;
        height: 45px;
        text-align: center;
        width:$date-width;
        float: left;
        border-left: 1px solid $border-color;
        border-bottom: 1px solid $border-color;
        padding:0px 10px;
      }

      .date-total{
        line-height: 45px;
        height: 45px;
        text-align: center;
        width:50px;
        float: left;
        border-left: 1px solid $border-color;
        border-bottom: 1px solid $border-color;
      }

      .border-b{
        border-bottom: 1px solid $border-color;
      }

    }

    .row-right-container{
      width:$width;
      min-height:45px;
      display: block;
      float: right;
      border-left: 1px solid $border-color;
    }
  }

  .add-project-item{
    width: $total_width;
    height: 90px;
    float: left;
    display: block;
    background:#fff;
    clear: both;
  }

  .chart-header-container{
    width:$total_width;
    height:auto;
    float: left;
  }

  .chart-header{
    height: $header-height;
    width:100%;
    display: block;
    float: left;
    /*box-sizing: border-box;*/
    overflow: hidden;

    .cell-group{
      width:$cell-group-width;
      height:$header-height;
      display: inline-block;
      float: left;
      box-sizing: border-box;
      border:1px solid $border-color;
      border-right:none;
      &:last-child{
        border-right:1px solid $border-color;
      }
    }

    .cell-title{
      width:100%;
      height:$header-height*0.5 ;
      display: block;
      text-align: center;
      font-family:'微软雅黑';
      color: black;
      font-size: 16px;
      line-height: $header-height*0.5 ;
      box-sizing: border-box;
      border-bottom: 1px solid $border-color;
    }

    .cell-date{
      width:$cell-width - 1px;
      height:$header-height*0.5 ;
      display: block;
      float: left;
      text-align: center;
      line-height:$header-height*0.5 ;
      font-family: '微软雅黑';
      font-size: 14px;
      color: black;
      border-right: 1px solid $border-color;
      &:last-child{
        border-right:none;
      }
    }
  }

  .edited-lbl{
    width:80px;
    height: 25px;
    line-height: 25px;
    text-align: center;
    text-overflow: ellipsis;
    white-space: nowrap;
    overflow: hidden;
    vertical-align: middle;
    display: inline-block;
  }

  .add-project-icon{
    width:20px;
    height:20px;
    display: inline-block;
    background-image: url('../../../assets/images/add_item.png');
    background-size:cover ;
    vertical-align: middle;
    margin-left: 10px;
  }

  .clearfix{
    clear: both;
  }

  .legend{
    width:100%;
    clear: both;
    float: left;
    height: 120px;
    display: block;
    line-height: 60px;

    .legend-title{
      width:300px;
      text-align: center;
      clear: both;
      display: block;
      height: 60px;
      color: #777;
      font-size: 26px;
      font-family: '微软雅黑';

      word-spacing: 5px;
    }


    .legend-item{

      width:150px;
      height: 60px;
      float: left;
      display: block;
      text-align: center;

    }

    .legend-text{
      color: #5a5a5a;
      vertical-align: middle;
    }

    .color-block{
      width:40px;
      height: 20px;
      margin-right: 10px;
      display: inline-block;
      background: red;
      vertical-align: middle;
    }

    .color-check{
      background: #00C6F0;
    }

  }

</style>

<template>
  <div class="container">
    <div class="legend" v-if="editable">
    <div class="legend-title">图例</div>
    <div class="legend-item">
    <span class="color-block"></span>
    <span class="legend-text">进度安排</span>
    </div>
    <div class="legend-item">
    <span class="color-block color-check"></span>
    <span class="legend-text">检查安排</span>
    </div>
    </div>
    <!--头部-->
    <div class="chart-container-wrapper" style="background: white">
      <!--头部-->
      <div class="chart-header-container">
        <div class="chart-left-header">
          <span class="number-item">序号</span>
          <span class="project-item">工程名称</span>
          <span class="project-subitem">分项工程</span>
          <span class="date-item">开始时间</span>
          <span class="date-item">结束时间</span>
          <span class="total-date">天数</span>
        </div>
        <div class="chart-right-header">
          <div class="chart-header" ref="container">
            <div class="cell-group" ref="group" v-for="(item,index) in monthCounter">
              <span class="cell-title">{{setMonthTitle(index)}}</span>
              <span class="cell-date" :data-date="setMonthTitle(index)+'-'+setDateText(subIndex,index)"
                    v-for="(subItem,subIndex) of 6">
              {{setDateText(subIndex,index)}}</span>
            </div>
          </div>
        </div>
      </div>

      <div class="chart-body-container">
        <div class="chart-project-item" v-for="(item,parentIndex) in project">
          <!--项目序号-->
          <div class="row-number" :style="{lineHeight:(getSubprojectSize(parentIndex)*45-1)+'px'}">
            {{parentIndex+1}}
          </div>

          <!--项目名称-->
          <div class="row-project" :title="item.projectName"
               :style="{lineHeight:(getSubprojectSize(parentIndex)*45-1)+'px'}">
            <!--项目的名称 v-if="stateArray[parentIndex].state" -->
            <el-input   v-if="getState(parentIndex)" :autofocus="true"
                        placeholder="请输入" v-model="item.projectName"  @blur="toggleInput($event,parentIndex)">
            </el-input>
            <span v-else @click.prevent="toggleInput($event,parentIndex)">{{item.projectName}}</span>
          </div>

          <!--子项目-->
          <div class="row-sub-container">
            <template  v-for="(subItem,index) in item.items">
              <div class="subproject-item">
                <!--子项目名称输入框-->
                <el-input v-if="getState(parentIndex,index*3)" :autofocus="true"
                          placeholder="请输入" v-model="subItem.subName" @blur="toggleInput($event,parentIndex,index,index*proCounter)">
                </el-input>
                <!--子项目名称显示label-->
                <span class="edited-lbl" v-else @click.prevent="toggleInput($event,parentIndex,index,index*proCounter)"
                      :title="subItem.subName">
                  {{subItem.subName}}
                </span>
                <!--新增子项目的按钮-->
                <span class="add-project-icon" v-if="!getState(parentIndex,index*3)&&!readOnly"
                      @click="addSubProject(parentIndex,index)"></span>
              </div>
              <div class="begin-date">
                <!--如果是没有保存的结束日期，就直接显示 @focus="setInvisible(parentIndex)"-->
                <el-input v-if="getState(parentIndex,index*proCounter+1)"
                          v-model="subItem.startDate" @blur="toggleInput($event,parentIndex,index,index*proCounter+1)"
                          type="date"
                          placeholder="选择日期" :autofocus="true" @change="changeDate(subItem)"  >
                </el-input>
                <!--如果是已经保存了结束日期就直接显示-->
                <span v-else @click.prevent="toggleInput($event,parentIndex,index,index*proCounter+1)">
                  {{subItem.startDate}}
                </span>
              </div>
              <div class="end-date">
                <el-input v-if="getState(parentIndex,index*proCounter+2)"
                          v-model="subItem.endDate"
                          type="date" @blur="toggleInput($event,parentIndex,index,index*proCounter+2)"
                          placeholder="选择日期" :autofocus="true">
                </el-input>
                <span v-else @click.prevent="toggleInput($event,parentIndex,index,index*proCounter+2)">
                  {{subItem.endDate}}
                </span>
              </div>
              <div class="date-total">{{getDateDistance(subItem.startDate,subItem.endDate)}}</div>
            </template>
          </div>

          <!--右边的展示列-->
          <div class="row-right-container">
            <chart-line  v-for="(subItem,index) in item.items" :size="getSize(subItem)" :width="itemWidth"
                         :start-date="subItem.startDate" :end-date="subItem.endDate" ref="charts">
              <template>
                {{subItem.startDate}}-{{subItem.endDate}}
              </template>
            </chart-line>
          </div>
        </div>
        <div class="add-project-item" @click="addProjectItem"></div>
        <div class="clearfix"></div>
      </div>

    </div>
  </div>

</template>

<script>

  'use strict';

  import  ChartLine from "./Sub";

  import  { DatePicker,Input } from "element-ui";

  /**
   * header的Group的宽度
   */
  const GROUP_LENGTH=240;

  /**
   * header的单元格的宽读
   */
  const CELL_WIDTH=50;

  /**
   * 甘特图组件
   */
  export default {
    components:{
      ChartLine,
      ElDatePicker:DatePicker,
      ElInput:Input
    },
    props:{
      readOnly:{
        type:Boolean,
        required:false,
        default:false
      },
      project:{
        type:Array,
        required:false,
        default:[]
      }
    },
    data () {
      return {
        remDate:null,
//        mouthCounter:-1,
        itemWidth:0,
        stateArray:[],
        monthCounter:2
        /*,
        project:[
          {
            projectName:"项目1",
            items:[{
              subName:"子选项1",
              startDate:'2015-11-18',
              endDate:'2015-12-15'
            },{
              subName:"子选项2",
              startDate:'2015-11-1',
              endDate:'2016-2-29'
            }]
          },
          {
            projectName:"项目3",
            items:[{
              subName:"子选项3",
              startDate:'2017-4-18',
              endDate:'2017-6-2'
            },{
              subName:"子选项4",
              startDate:'2016-2-28',
              endDate:'2016-3-28'
            }]
          },{
            projectName:"项目5",
            items:[{
              subName:"子选项6",
              startDate:'2015-11-18',
              endDate:'2015-12-15'
            },{
              subName:"子选项7",
              startDate:'2015-11-1',
              endDate:'2016-2-29'
            }]
          },
          {
            projectName:"项目6",
            items:[{
              subName:"子选项8",
              startDate:'2013-9-6',
              endDate:'2017-6-15'
            },{
              subName:'子选项9',
              startDate:'2016-2-28',
              endDate:'2016-3-28'
            }]
          }
        ]
        */
      }
    },
    computed: {
      proCounter () {
        return this.getPropertyCounter({
          subName:'子选项9',
          startDate:'2016-2-28',
          endDate:'2016-3-28'
        });
      }
    },
    watch:{
      project(newValue,old){

        console.log(JSON.stringify({old}));

        console.log(JSON.stringify({newValue}));

        /**
         * 在这儿维护那个状态数组
         */
        for(var i=0;i<this.project.length;i++){

          var target=this.project[i];

          var tempObj={

          };

          for( var key in target){

            if (target[key] instanceof Array){

              var arr=[];

              for (var k=0;k<target[key].length;k++){

                //arr.push(0);

                var subTarget=target[key][k];

                for (var subKey in subTarget){

                  if(subTarget.hasOwnProperty(subKey)){

                    arr.push({state:0});
                  }

                }

              }

              tempObj.subState=arr;

            }
            else{

              tempObj.state=0;

            }
          }

          this.stateArray.push(tempObj);
        }

        this.DrawHeader();

        this.setContainerSize();

      }
    },
    updated(){

      this.setContainerSize();

    },
    beforeMount(){
    },
    mounted () {
      //第一次加载的时候 渲染默认的宽度
      //this.setContainerSize();
    },
    methods: {
      /**
       * 为了避免渲染的时候，出现错误。
       */
      getState(pIndex,subIndex){

        try{

          if(subIndex==undefined)
          {
            return this.stateArray[pIndex].state;
          }
          else
          {
            return this.stateArray[pIndex].subState[subIndex].state
          }

        }
        catch(Exception){

          return false;

        }

      },

//        setInvisible(index){
//
//          this.$refs['charts'][index].$el.children[0].style.opacity=0;
//
//        },
      /**
       *
       */
      changeDate(target){

//         var start=new Date(target.startDate);
//
//         var end=new Date(target.endDate);
//
//         if(start>end){
//
//           this.DrawHeader();
//
//         }

      },
      /**
       * 新增一个子项目
       */
      addSubProject(parentIndex,index){

        if (this.readOnly){
          return;
        }

        this.project[parentIndex].items.splice(index+1,0,{
          subName:"待编辑子项目",
          startDate:this.remDate.start,
          endDate:this.remDate.start
        });

        this.stateArray[parentIndex].subState.splice((index+1)*this.proCounter,0,{state:0},{state:0},{state:0});

      },
      //显示或者隐藏输入框的状态
      /**
       *事件原对象 type 输入框类型 父级索引 子级索引 偏移量
       */
      toggleInput($event,index,subIndex,offset){

        if(this.readOnly){
          return ;
        }
        //offset是基于subIndex

        var target=$event.target;

        var tempStr=target.value;

        if (subIndex==undefined){

          this.stateArray[index].state=!this.stateArray[index].state;

          //删除项目
          if(tempStr!=undefined&&tempStr.replace(/(^\s*)|(\s*$)/g,'')==""){
            this.project.splice(index,1);
          }

        }
        else {

          this.stateArray[index].subState[offset].state=!this.stateArray[index].subState[offset].state;

          if(tempStr!=undefined&&tempStr.replace(/(^\s*)|(\s*$)/g,'')==""&&target.type!='date'){

            this.project[index].items.splice(subIndex,1);

            //删除状态数组
            this.stateArray[index].subState.splice(subIndex*this.proCounter,subIndex*this.proCounter+1,subIndex*this.proCounter+2,3);

            /*
            * 如果子项目为0的时候，删除整个项目
            **/
            if(this.project[index].items.length==0){

              this.project.splice(index,1);

              this.stateArray.splice(index,1);

            }

          }

        }

        if (target.type=='date'){

          var dateTarget=this.project[index].items[subIndex];

          var _start=new Date(dateTarget.startDate);

          var _end=new Date(dateTarget.endDate);

          if (dateTarget.startDate==""){
            dateTarget.startDate=this.remDate.start;
          }

          if (dateTarget.endDate==""){
            dateTarget.endDate=this.remDate.end;
          }

          if (_start>_end){
            dateTarget.endDate=dateTarget.startDate;
          }

        }

        //因为输入的时间已经变化了，重绘画整个表格
        this.DrawHeader();

      },
      /**
       * 新建一个可以编辑的项目
       */
      addProjectItem(){
        this.project.push({
          projectName:"待编辑项目",
          items:[
            {
              subName:"待编辑子项目",
              startDate:this.remDate.start,
              endDate:this.remDate.start
            }]
        });

        /*
        *  继续在这儿还是要维护状态数组
        */
        var tempObj={
          state:0,
          subState:[]
        };

        for(var i=0;i<this.proCounter;i++){
          tempObj.subState.push({state:0});
        }

        this.stateArray.push(tempObj);

      },
      /**
       * 是否是闰年
       * @returns {boolean}
       */
      isLeapYear(Year){

        var year=Year|| this.year;

        return (year%4==0&&year%100!=0)||year%400==0;
      },
      /**
       * 重绘header中日历的个数
       */
      DrawHeader(){

        var start=null,end=null;

        /**
         * 初始化参数
         */
        if (this.project.length<=0){

          var tempDate=new Date();

          start=tempDate.getFullYear()+"-"+(tempDate.getMonth()+1)+"-"+tempDate.getDate();

          tempDate.setMonth(tempDate.getMonth()+2);

          end=tempDate.getFullYear()+"-"+(tempDate.getMonth()+1)+"-"+tempDate.getDate();

        }

        var tempArr=[];

        for (var i=0;i<this.project.length;i++){
          tempArr =  tempArr.concat(this.project[i].items);
        }

        for (var i=0;i<tempArr.length;i++){

          if(start==null){
            start=tempArr[i].startDate;
          }
          else{

            var startDate=new Date(start);

            var tempDate1=new Date(tempArr[i].startDate);

            if (tempDate1<startDate){
              start=tempArr[i].startDate;
            }

          }

          if(end==null){
            end=tempArr[i].endDate;
          }
          else{

            var endDate=new Date(end);

            var tempDate2=new Date(tempArr[i].endDate);

            if (tempDate2>endDate){
              end=tempArr[i].endDate;
            }
          }
        }

        this.monthCounter=this.getMonthDistance(start,end);

        /**
         * 为了防止月份太少 把header撑不满的情况
         */
        if(this.monthCounter<2){
          this.monthCounter=2;
        }

        this.remDate={start,end};

      },
      /**
       * 重新根据格子的个数设置容器的宽度
       */
      setContainerSize(){

        if (this.$refs['group']==undefined){
          return ;
        }

        var length=this.$refs['group'].length;

        if(length<2){
          return ;
        }

        this.$refs['container'].style.width=(length*GROUP_LENGTH)+'px';

        this.itemWidth=(length*GROUP_LENGTH);
      },
      /**
       * 获取现在的月份有多少天
       * @returns {number}
       */
      getCurrentMonthTotal(Year,Month) {

        var month = Month || this.month;

        var total = -1;

        switch (month) {
          case 1:
          case 3:
          case 5:
          case 7:
          case 8:
          case 10:
          case 12:
            total = 31;
            break;
          case 4:
          case 6:
          case 9:
          case 11:
            total = 30;
            break;
          default:
            if (this.isLeapYear(Year)) {
              total = 29;
            }
            else {
              total = 28
            }
            break;
        }

        return total;
      },
      /**
       * 计算两个日期之间相差多少的月份 这个东西比较特别 比如 2017-1-1跟2017-2-1相差2
       */
      getMonthDistance(start,end){

        var startDate=new Date(start);

        var endDate=new Date(end);

        var year_length=(endDate.getFullYear()-startDate.getFullYear())*12;

        var startMonth=startDate.getMonth()+1;

        var endMonth=year_length+endDate.getMonth()+1;

        return endMonth-startMonth+1;
      },
      /**
       * 获取两个日期之间相差的天数 头和尾都要算 比如 2017-2-1跟2017-2-2 是两天
       */
      getDateDistance(start,end){

        var dateStart=new Date(start);

        var dateEnd=new Date(end);

        var timespan=dateEnd.getTime()- dateStart.getTime();

        return Math.floor(timespan/(1000 * 60 * 60 * 24))+1;

      },
      /**
       * 设置合并的标题 用于显示月份
       */
      setMonthTitle(index){

        /**
         * 初始化的时候，用户还没有传入开始和结束时间
         */
        if(this.remDate==null){

          var now =new Date();

          var nowText=now.getFullYear()+"-"+(now.getMonth()+1)+"-1";

          var __month=now.getMonth()+1;

          var next=new Date(now);

          var nextText=next.getFullYear()+"-"+(next.getMonth()+1)+"-1";

          this.remDate={
            start:nowText,
            end:nextText
          }
        }

        var date=new Date(this.remDate.start);

        var month=date.getMonth();

        month+=index;

        date.setMonth(month);

        return date.getFullYear()+"-"+(date.getMonth()+1);
      },
      /**
       * 设置每个单元格子里面
       * @param subIndex
       * @param index
       * @returns {*}
       */
      setDateText(subIndex,index){

        if (subIndex+1!=6){
          return 5*(subIndex+1);
        }
        else {

          var date= new Date(this.setMonthTitle(index)+"-1");

          return this.getCurrentMonthTotal(date.getFullYear(),date.getMonth()+1);

        }
      },
      /**
       * 返回横道行在图上的位置
       * */
      getSize(dateParam){


        var {startDate,endDate}=dateParam;

        if (!startDate||!endDate){
          return {width:0,left:0};
        }

        var start=new Date(startDate);

        var end=new Date(endDate);

        /**
         * 为了怕出现开始时间和结束时间是相同一天的极端情况
         */
        if ((start.getTime()-end.getTime())/1000<24*3600){

          end.setMonth(end.getMonth()+1);

        }


        var tempDate1=new Date(this.remDate.start);

        //得到最左边开始的日期
        var mostLeft=tempDate1.getFullYear()+"-"+(tempDate1.getMonth()+1)+"-1";

//          var tempDate2=new Date(this.remData.end);
//
//          //得到最右边的结束的日期
//          var mostRight=tempDate2.getFullYear()+"-"+(tempDate2.getMonth()+1)+"-1";

        //得到整数部分的长度

        var tempNum=this.getMonthDistance(mostLeft,start)-1;

        var distance1=(tempNum)*GROUP_LENGTH;

        //计算额外的部分 直接舍去，为了怕出现小数
        var othedDistance=Math.floor(start.getDate()/this.getCurrentMonthTotal(start.getFullYear(),start.getMonth()+1)*GROUP_LENGTH);

        distance1+=othedDistance;

        //得到整数部分的长度+开始月多出的长度+结束月多出的长度
        var tempNum2=this.getMonthDistance(startDate,endDate)-2;

        var distance2=tempNum2*GROUP_LENGTH;

        //开始月多出来的长度
        var leftDis=(1-start.getDate()/this.getCurrentMonthTotal(start.getFullYear(),start.getMonth()+1))*GROUP_LENGTH;

        distance2+=leftDis;

        var rightDis=Math.floor(end.getDate()/this.getCurrentMonthTotal(end.getFullYear(),end.getMonth()+1)*GROUP_LENGTH);

        distance2+=rightDis;

        return {width:distance2,left:distance1};
      },
      /**
       * 计算项目的子项目的个数 用于设置行高
       * @param index
       * @returns {number}
       */
      getSubprojectSize(index){

        try{

          if (!this.project[index].items||this.project[index].items.length<=0){
            return 1;
          }

          return this.project[index].items.length;

        }
        catch(ex){

          return 1;

        }

      },
      getPropertyCounter(target){

        var counter=0;

        for (var key in target){

          if (target.hasOwnProperty(key)){
            counter++;
          }

        }

        return counter;
      }
    }
  }

</script>
